(deffunction pobierz_liczbe (?limit_low ?limit_high)
   (bind ?liczba (read))
   (while(or (not (integerp ?liczba))
             (< ?liczba ?limit_low)
             (> ?liczba ?limit_high)
         )
      (format t "%nPodales zla liczbe, sprobuj ponownie <%d,%d>:" ?limit_low ?limit_high)
      (bind ?liczba (read))
   )
   (printout t crlf)
   ?liczba
)


(deffunction pobierz_tak_nie ()
   (bind ?odp (readline))
   (bind ?odp (lowcase ?odp))
   (while(and (<> 0 (str-compare ?odp "tak")) (<> 0 (str-compare ?odp "nie")))
      (printout t "<tak | nie>: ")
      (bind ?odp (readline))
   )
   (printout t crlf)
   ?odp
)

(deffunction pobierz_typ()
   (bind ?typ (readline))
   (bind ?typ (lowcase ?typ))
   (while(and (<> 0 (str-compare ?typ "sniadanie")) (<> 0 (str-compare ?typ "obiad")) (<> 0 (str-compare ?typ "kolacja")) (<> 0 (str-compare ?typ "deser")))
      (printout t "<sniadanie | obiad | kolacja | deser>: ")
      (bind ?typ (readline))
   )
   (printout t crlf)
   ?typ
)

(deffunction pobierz_trudnosc ()
   (bind ?trudnosc (readline))
   (bind ?trudnosc(lowcase ?trudnosc))
   (while(and (<> 0 (str-compare ?trudnosc "latwa")) (<> 0 (str-compare ?trudnosc "srednia")) (<> 0 (str-compare ?trudnosc "trudna")))
      (printout t "<latwa | srednia | trudna>: ")
      (bind ?trudnosc (readline))
   )
   (printout t crlf)
   ?trudnosc
)




(defrule start
	(initial-fact)
=>
	(printout t "Podaj typ posilku : sniadanie | obiad | kolacja | deser " crlf)
	(bind ?typ (pobierz_typ))
	(assert(typ ?typ))
	
)
(deftemplate potrawa
	"potrawa"
	(slot nazwa
		(type STRING)
        )
	(slot typ
		(type STRING)
        )
		
	(slot trudnosc
		(type STRING)
        )
	(slot czas
		(type INTEGER)
	)
	(slot kalorie
		(type INTEGER)
        )
        
	(slot koszt
		(type INTEGER)
	)
        (slot wegetarianin
                (type STRING)
        )
	
)
(defglobal
  ?*minkaloriemax* = 999999
  
)
(deffacts potrawy




(potrawa (nazwa "zupka")(typ "obiad")(trudnosc "srednia")(czas 10)(kalorie 150)(koszt 10)(wegetarianin "nie"))
(potrawa (nazwa "zupka1")(typ "obiad")(trudnosc "srednia")(czas 20)(kalorie 200)(koszt 20)(wegetarianin "nie"))
(potrawa (nazwa "zupka2")(typ "obiad")(trudnosc "srednia")(czas 40)(kalorie 100)(koszt 100)(wegetarianin "nie"))
(potrawa (nazwa "zupka3")(typ "obiad")(trudnosc "srednia")(czas 30)(kalorie 400)(koszt 50)(wegetarianin "nie"))
(potrawa (nazwa "zupka4")(typ "obiad")(trudnosc "srednia")(czas 40)(kalorie 350)(koszt 80)(wegetarianin "nie"))
)
(defrule pytania
	(typ ?typ)
=>
(printout t "Podaj trudnosc przygotowania posilku: latwa | srednia | trudna"  crlf)
	(bind ?trudnosc (pobierz_trudnosc))
     (assert(trudnosc ?trudnosc))
	(printout t "Ile czasu mozesz poswiecic na przygotowanie potrawy (podaj w minutach)" crlf)
	(bind ?czas (pobierz_liczbe 1 300))
    (assert(czas ?czas))
	(printout t "Minimalna ilosc kalorii jaka moze zawierac posilek? " crlf)
	(bind ?kaloriemin (pobierz_liczbe 0 5000))
    (assert(kaloriemin ?kaloriemin))
        (printout t "Maksymalna ilosc kalorii jaka moze zawierac posilek (max 5000)? " crlf)
	(bind ?kaloriemax(pobierz_liczbe 0 5000))
	(assert(kaloriemax ?kaloriemax))
        (printout t "Czy posilek ma byc wegetarianski?" crlf)
	(bind ?wegetarianin(pobierz_tak_nie))
	(assert(wegetarianin ?wegetarianin))
	(printout t "Ile maksymalnie mozesz przeznaczyc pieniedzy na przygotowanie posilku?" crlf)
	(bind ?koszt (pobierz_liczbe 1 500))
	(assert(koszt ?koszt))
)
(defrule pytania1
	(typ ?typ)(or(trudnosc ?trudnosc) ) (or (czas ?czas) ) (or(kaloriemin ?kaloriemin)) (or(kaloriemax ?kaloriemax)) (or(wegetarianin ?wegetarianin)) (or(koszt ?koszt))
=>
	(printout t " ,typ" typ:  ?typ " ,trudnosc: " ?trudnosc " ,czas: " ?czas "  ,kaloriemin: " ?kaloriemin "  ,kaloriemax: " ?kaloriemax " ,wegetarianin: " ?wegetarianin " ,koszt: " ?koszt crlf)
	
	
)
(defrule usun_typ_sniadanie	
	(or(typ "obiad")(typ "kolacja")(typ "deser"))
	?usun<-(potrawa (nazwa ?nazwa)(typ "sniadanie"))




	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)




)
(defrule usun_typ_obiad
	(or(typ "sniadanie")(typ "kolacja")(typ "deser"))
	?usun<-(potrawa (nazwa ?nazwa)(typ "obiad"))




	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)

)
(defrule usun_typ_kolacja	
	(or(typ "obiad")(typ "sniadanie")(typ "deser"))
	?usun<-(potrawa (nazwa ?nazwa)(typ "kolacja"))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)
)
(defrule usun_typ_deser	
	(or(typ "obiad")(typ "kolacja")(typ "sniadanie"))
	?usun<-(potrawa (nazwa ?nazwa)(typ "deser"))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)
)

(defrule usun_trudnosc_latwa	
	(or(trudnosc "trudna")(trudnosc "srednia"))
	?usun<-(potrawa (nazwa ?nazwa)(trudnosc "latwa"))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)

)


(defrule usun_trudnosc_srednia	
	(or(trudnosc "trudna")(trudnosc "latwa"))
	?usun<-(potrawa (nazwa ?nazwa)(trudnosc "srednia"))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)
)

(defrule usun_trudnosc_trudna
	(or(trudnosc "srednia")(trudnosc "latwa"))
	?usun<-(potrawa (nazwa ?nazwa)(trudnosc "trudna"))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)
)

(defrule usun_czas
	(czas ?x)
	?usun<-(potrawa (nazwa ?nazwa)(czas ?czas))
	(test (> ?czas ?x))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)
)

(defrule usun_kalorie_min
	(kaloriemin ?x)
	?usun<-(potrawa (nazwa ?nazwa)(kalorie ?kalorie))
	(test (< ?kalorie ?x))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)
)

(defrule usun_kalorie_max
	(kaloriemax ?x)
	?usun<-(potrawa (nazwa ?nazwa)(kalorie ?kalorie))
	(test (> ?kalorie ?x))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)
)
(defrule usun_miesny
	(wegetarianin "tak")
	?usun<-(potrawa (nazwa ?nazwa)(wegetarianin "nie"))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)
)


(defrule usun_pieniadze
	(koszt ?x)
	?usun<-(potrawa (nazwa ?nazwa)(koszt ?koszt))
	(test (> ?koszt ?x))
	=>
	(printout t "Usunieto " ?nazwa crlf)
(retract ?usun)

)
(defrule nie_ma_nic
	(not(potrawa (nazwa ?nazwa)))
	=>	
(printout t "Przykro mi , ale nie znaleziono potrawy ktora spelnia twoje kryteria" crlf)
)

(defrule znajdz
  (declare (salience -1))
	(potrawa (nazwa ?nazwa) (kalorie ?kalorie))
	=>
	(assert(wybrana ?nazwa ?kalorie))
(printout t "potrawa spelniajaca wymagania: " ?nazwa  crlf)
)

(defrule najmniej_kaloryczny
(declare (salience -2))
	(wybrana ?nazwa ?kalorie)	
	(test (< ?kalorie ?*minkaloriemax*))
	=>
	
	(if (< ?kalorie ?*minkaloriemax*)
		then
			(bind ?*minkaloriemax* ?kalorie)
			)
	)

(defrule przypisz_najmniejsze
(declare (salience -3))
		
	=>
	(assert (najmniejszekalorie ?*minkaloriemax*) )	
)
(defrule znajdz_ostateczne
(declare (salience -4))
     (najmniejszekalorie ?x)
	(wybrana ?nazwa ?x)
	
	=>
	(assert (wyniczek ?nazwa ?x) )
	(printout t "Potrawa najmniej kaloryczna: " ?nazwa " , kalorie: " ?x crlf)
)






